/**
 * Copyright  2025, Hai Yue Xing He Technology Co., Ltd
 * 
 * @author          ZHAO LIMIN
 * @version         1.0.1
 * @since           2025-04
 * HYXHPolygon.ts   多段面的矢量图
 */
import { Vec3 } from "cc";
import { HGeometry, ILineIndex } from "./HYXHGeometry";
import { HYXHGeoTools} from "./HYXHGeoTools";
import { PointsCollection } from "./HYXHPointsCollection";
import { ICartesian } from "./Cartesian";
import { UNION_NUMBER_ARRAY } from "./HDataType";
import { Cartesian3 } from "./Cartesian3";
import { Check } from './Check'
import { defined } from './Defined'
/**
 * 矢量图
 */
export class HPolygon implements HGeometry {
    /**
     * Ring是一个封闭的Path，即起始点和终止点有相同的坐标值。Ring有内部和外部属性‌
     * 用来描述多段
     */
    public rings: Map<number, PointsCollection>;
    /*
     * 线段索引, 用于进行处理
     */
    public linesIndices: ILineIndex;
    /**
     * 点的坐标
     */
    public x: number;
    public y: number;
    public z: number;
    
    constructor() {
        this.rings = new Map<number, PointsCollection>();
        this.x = 0;
        this.y = 0;
        this.z = 0;
    }     
    /**
     * 
     * @param layer 层，作为indexK EY
     * @param array 数据数组
     * @param startIndex 
     */   
    pack(layer: number, array: UNION_NUMBER_ARRAY, startIndex: number): UNION_NUMBER_ARRAY {
        Check.defined('array', array)
        if (!defined(array)) {
            array = new Array<number>(); 
        }
        if (startIndex < 0) {
            startIndex = 0; 
        }
        if ( this.rings.size == 0) {
            return array;
        }
        if (this.rings.has(layer) === false) {
            return array;
        }

        let ring = this.rings.get(layer);
        ring.pack(array, startIndex);
        return array;
    }
    unpack(layer: number, array: UNION_NUMBER_ARRAY, startIndex: number) {
        Check.defined('array', array);
        if (startIndex < 0) {
            startIndex = 0;
        }
        if ( this.rings.size == 0) {
            return array;
        }
        if (this.rings.has(layer) === false) {
            return array;
        }

        let ring = this.rings.get(layer);
        let count = ring.unpack(array, startIndex);
        return count;       
    }
    pckagedLength(): number {
        return Cartesian3.packedLength;
    }
    pushBack(layer: number, newPoint: ICartesian): number {
        Check.defined('newPoint', newPoint);
        if (this.rings.has(layer) === false) {
           this.rings.set(layer, new PointsCollection()); 
        }
        let ring = this.rings.get(layer);
        ring.push(newPoint);
        return ring.length;
    }
    equals(other: HGeometry): boolean {
        if ( !defined(other)) {
            return false; 
        }
        if (!(other instanceof HPolygon)) {
            return false; 
        }
        if (this.rings.size != other.rings.size) {
            return false; 
        }
        for (let key of this.rings.keys()) {
            const ring = this.rings.get(key);
            let _same = false;
            for(let key2 of other.rings.keys()) {
                const ring2 = other.rings.get(key2);
                if(ring.equals(ring2)){
                    _same = true;
                    break;
                } 
            }
            if (_same === false) {
                return false; 
            }
        }
        return true;
    }
    update(): boolean {
        throw new Error("Method not implemented.");
    }
}